package net.zjitc.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.zjitc.common.ResponseResult;
import net.zjitc.common.lang.Const;
import net.zjitc.entity.Manager;
import net.zjitc.entity.Permission;
import net.zjitc.entity.Role;
import net.zjitc.entity.Vo.ManagerVo;
import net.zjitc.exception.ManagerException;
import net.zjitc.mapper.ManagerMapper;
import net.zjitc.mapper.PermissionMapper;
import net.zjitc.mapper.RoleMapper;
import net.zjitc.service.ManagerService;
import net.zjitc.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Transactional
@Service
public class IManagerService implements ManagerService {

    @Autowired
    private ManagerMapper managerMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    //查询所有
    @Override
    public List<Manager> selectAll() {
        return managerMapper.selectList(null);
    }

    //分页功能
    @Override
    public Page<ManagerVo> selectPage(String query, Integer pagenum, Integer pagesize) {
        Page<ManagerVo> page = new Page<>(pagenum, pagesize);
        page = managerMapper.selectManagerVo(page);
        return page;
    }

    @Override
    public ResponseResult addUsers(ManagerVo managerVo) {
        ResponseResult<Manager> res = new ResponseResult<>();
        if (managerVo.getUsername() == null || managerVo.getPassword() == null) {
            res.setError("用户名或密码不能为空");
            return res;
        }

        Manager manager1 = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
                .eq(Manager::getUsername, managerVo.getUsername()));
        if (manager1 != null) {
            res.setUnprocesableEntity("用户名已存在");
            return res;
        }

        Date date=new Date();
        managerVo.setRid(0);
        managerVo.setType(1);
        managerVo.setMg_time((int)(System.currentTimeMillis()/1000));
        //加密密码
        managerVo.setPassword(bCryptPasswordEncoder.encode(managerVo.getPassword()));
        int insert = managerMapper.insert(managerVo);
        if (insert != 0) {
            managerVo.setPassword(null);
            managerVo.setCreate_time(date);
            managerVo.setMg_time(null);
            res.setCreated("创建成功", managerVo);
        } else {
            res.setUnprocesableEntity();
        }
        return res;
    }

    @Override
    public ResponseResult selectById(Integer id) {
        ResponseResult<Manager> res = new ResponseResult<>();
        //不查哪些字段
//        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
//                .select(info-> !(info.getProperty().equals("password")
//                ||info.getProperty().equals("type")
//                )).eq(Manager::getId, id));

        //只查哪些字段
        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
                .select(Manager::getId, Manager::getUsername,
                        Manager::getRid, Manager::getMobile,
                        Manager::getEmail).eq(Manager::getId, id));

        if (manager != null) {
            res.setSuccess("查询成功", manager);
        } else {
            res.setUnprocesableEntity("查询失败");
        }
        return res;

    }

    @Override
    public ResponseResult updateType(Integer uId, Boolean type) {
        ResponseResult<Manager> res=new ResponseResult();
        Manager manager = managerMapper.selectById(uId);
        if (manager==null){
            res.setUnprocesableEntity("用户不存在");
            return res;
        }
        manager.setType(type?1:0);
        managerMapper.updateById(manager);
        manager.setPassword(null);
        res.setSuccess("设置状态成功",manager);
        return res;
    }

    @Override
    public ResponseResult updateUser(Long id, Manager manager) {
        ResponseResult<Manager> res=new ResponseResult<>();
        Manager manager1 = managerMapper.selectById(id);
        if (manager1==null){
            res.setUnprocesableEntity("用户不存在");
            return res;
        }
        //防止空指针异常
        if (manager==null){
            manager=new Manager();
        }
        if (manager.getEmail()!=null){
            manager1.setEmail(manager.getEmail());
        }
        if (manager.getMobile()!=null){
            manager1.setMobile(manager.getMobile());
        }
        manager1.setPassword(null);
        manager1.setType(null);
        manager1.setMg_time(null);
        int update = managerMapper.updateById(manager1);
        if (update!=0){
            res.setSuccess("更新成功",manager1);
        }else{
            res.setError("更新失败");
        }
        return res;
    }

    @Override
    public ResponseResult deleteUser(Integer id) {
        ResponseResult res=new ResponseResult();
        int delete = managerMapper.deleteById(id);
        if (delete!=0){
            res.setSuccess("删除成功");
        }else{
            res.setError("删除失败");
        }
        return res;
    }

    /**
     * 登录成功处理器调用,用户已经认证成功
     * @param username
     * @return
     */
    @Override
    public ResponseResult<Manager> selectByUsername(String username) {
        ResponseResult<Manager> res=new ResponseResult<>();
        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class).eq(Manager::getUsername, username)
                .select(info -> !(info.getColumn().equals("mg_pwd")
                        ||info.getColumn().equals("mg_state")
                        ||info.getColumn().equals("mg_time")))
        );

        res.setSuccess("登录成功",manager);

        return res;
    }

    @Override
    public ResponseResult<Manager> giveManagerRole(Long id, Manager manager) throws ManagerException {
        ResponseResult<Manager> res=new ResponseResult<>();
        if (manager.getRid()==null){
            throw new ManagerException("传入的参数为空");
        }
        Manager manager1 = managerMapper.selectById(id);
        manager1.setRid(manager.getRid());
        int update = managerMapper.update(manager1, Wrappers.<Manager>lambdaUpdate().eq(Manager::getId, manager1.getId()).set(Manager::getRid, manager1.getRid()));
        if (update!=0){
            manager1.setPassword(null);
            manager1.setType(null);
            manager1.setMg_time(null);
            //清除原有在redis中的信息
            clearUserAuthorityInfo(manager1.getUsername());
            res.setSuccess("设置角色成功",manager1);
        }else{
            res.setNotFound("设置失败,用户不存在");
        }
        return res;
    }

    @Override
    public Manager getByUsername(String username) {
        return managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class).eq(Manager::getUsername,username));
    }

    @Override
    public String getUserAuthirutyInfo(Manager manager) {
        //从缓存中读取数据(但是当相关的角色权限发生了改变,应该立刻删除缓存)
        if (redisUtil.hasKey(Const.PRE_USERNAME + manager.getUsername())){
            return (String)redisUtil.get(Const.PRE_USERNAME + manager.getUsername());
        }

        //通过拼接字符串的方式来
        String authority="";

        //获取角色操作权限
        if (manager.getRid()!=0){
            Role role = roleMapper.selectById(manager.getRid());
            if (role!=null){
                //菜单操作权限
                authority+="ROLE_"+role.getRoleName()+","+role.getPsIds();
            }
        }else{
            //roleid为0则是超级管理员[ADMIN],拥有所有的权限
            List<Permission> permissions = permissionMapper.selectList(null);
            authority+="ROLE_ADMIN,"+permissions.stream().map(p -> p.getId().toString()).collect(Collectors.joining(","));
        }

        //用户相关的权限添加到缓存中(一个小时)
        redisUtil.set(Const.PRE_USERNAME+manager.getUsername(),authority,60 * 60);

        return authority;
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del(Const.PRE_USERNAME+username);
    }


}
